import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * 
 * @author Devin Wolanick
 * @Version 1.0
 * 
 * View for BlackJack GUI
 */
public class BJview {
	
	/**
	 * Variables
	 */
	private JFrame mainFrame;
	private JPanel dealersHandPanel;
	private JPanel dealersInfoPanel;
	private JCheckBox debugCheckBox;
	private JCheckBox luckyCheckBox;
	private ArrayList<JPanel> playersHandPanels    = new ArrayList<JPanel>();
	private ArrayList<JPanel> playersValuePanels   = new ArrayList<JPanel>();
	private ArrayList<JButton> playersHitButtons   = new ArrayList<JButton>();
	private ArrayList<JButton> playersStandButtons = new ArrayList<JButton>();
	private ArrayList<JButton> playersDDButtons = new ArrayList<JButton>();
	private ArrayList<JButton> playersSurrenderButtons = new ArrayList<JButton>();
	private JButton btnNextHand;
	private JButton btnExport;
	private JButton forceStand = new JButton();
	private int numPlayers = 0;
	private int currentPlayer = 0;
	
	/**
	 * Sets up Game Options
	 * @param numPlayers Number of Players
	 * @param numDecks Number of Decks
	 */
	public void setUp(int numPlayers, int numDecks) {
    	this.numPlayers = numPlayers;
    	mainFrame = new JFrame("BlackJack");
    	mainFrame.setLocation(50, 300);
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //setUpAreas(mainFrame.getContentPane());
        mainFrame.getContentPane().add(new JLabel(new ImageIcon("image/greenFelt.png")));
        mainFrame.getGlassPane().setVisible(true);
        setUpAreas((Container) mainFrame.getGlassPane());
        
        //Frame Size
        if (numPlayers<3)
        	mainFrame.setSize(new Dimension((400),450));
        else if (numPlayers%2==0)
        	mainFrame.setSize(new Dimension((100*numPlayers), 680));
        else
        	mainFrame.setSize(new Dimension((100*(numPlayers+1)), 680));
        
        clearHands();
        mainFrame.setVisible(true);
        for (int i=1; i<playersHitButtons.size(); i++) {
        	playersHitButtons.get(i).setEnabled(false);
        	playersStandButtons.get(i).setEnabled(false);
        	playersDDButtons.get(i).setEnabled(false);
        	playersSurrenderButtons.get(i).setEnabled(false);
        }
    }
	
	/**
	 * Adds all components to Pane
	 * @param pane Pane to add to
	 */
//    private void setUpAreas(Container pane) {
	private void setUpAreas(Container pane) {
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
        pane.add(makeDealerArea());
        pane.add(makeButtonArea());
        pane.add(makePlayerArea());
    }
    
    /**
     * Creates Dealers Area
     * @return Dealers Area Panel
     */
    private JPanel makeDealerArea() {
    	JPanel dealerPanel = new JPanel();
    	dealerPanel.setOpaque(false);
    	dealerPanel.setMaximumSize(new Dimension(1000,200));
    	dealerPanel.setLayout(new BoxLayout(dealerPanel, BoxLayout.Y_AXIS));
    	dealerPanel.setVisible(true);
    	dealerPanel.add(dealersHand());
        dealerPanel.add(dealersInfo());
        return dealerPanel;
    }
    
    /**
     * Creates Dealers Hand Area
     * @return Dealers Hand Panel
     */
    private JPanel dealersHand() {
    	JPanel dealersHandPanel = new JPanel();
    	dealersHandPanel.setOpaque(false);
    	addCard(dealersHandPanel);
    	dealersHandPanel.setVisible(true);
    	this.dealersHandPanel = dealersHandPanel;
    	return dealersHandPanel;
    }
    
    /**
     * Creates Dealers Info Area
     * @return Dealers Info Panel
     */
    private JPanel dealersInfo() {
    	JPanel dealersInfoPanel = new JPanel();
    	dealersInfoPanel.setOpaque(false);
    	dealersInfoPanel.setLayout(new FlowLayout());
    	dealersInfoPanel.setVisible(true);
    	dealersInfoPanel.add(new JLabel("Dealers Value:"));
    	this.dealersInfoPanel = dealersInfoPanel;
    	return dealersInfoPanel;
    }

    /**
     * Creates Button Area
     * @return Button Panel
     */
    private JPanel makeButtonArea() {
    	JPanel buttonPanel = new JPanel();
    	buttonPanel.setOpaque(false);
    	buttonPanel.setMaximumSize(new Dimension(1000,200));
    	buttonPanel.setLayout(new FlowLayout());
    	buttonPanel.setVisible(true);
    	JButton nextHand = new JButton("Next Hand");
    	this.btnNextHand = nextHand;
    	buttonPanel.add(nextHand);
    	this.btnNextHand = nextHand;
    	btnNextHand.setEnabled(false);
    	JButton btnExport = new JButton("Export Data");
    	buttonPanel.add(btnExport);
    	this.btnExport = btnExport;
    	this.btnExport.setEnabled(false);
    	
    	JCheckBox debugCheckBox = new JCheckBox("Debug");    	
    	debugCheckBox.setOpaque(false);
    	debugCheckBox.setForeground(Color.WHITE);
    	this.debugCheckBox = debugCheckBox;
    	
    	JCheckBox countCheckBox = new JCheckBox("Counters");    	
    	countCheckBox.setOpaque(false);
    	countCheckBox.setForeground(Color.WHITE);
    	
    	JCheckBox luckyCheckBox = new JCheckBox("Lucky Lucky");    	
    	luckyCheckBox.setOpaque(false);
    	luckyCheckBox.setForeground(Color.WHITE);
    	this.luckyCheckBox = luckyCheckBox;
    	
    	JPanel checkBoxes = new JPanel();
    	checkBoxes.setLayout(new BoxLayout(checkBoxes, BoxLayout.Y_AXIS));
    	checkBoxes.setOpaque(false);
    	checkBoxes.add(debugCheckBox);
    	checkBoxes.add(countCheckBox);
    	buttonPanel.add(checkBoxes);
    	buttonPanel.add(luckyCheckBox);
    	return buttonPanel;
    }
    
    /**
     * Creates Players Area
     * @return Players Area Panel
     */
    private JPanel makePlayerArea() {
    	JPanel playerPanel = new JPanel();
    	playerPanel.setOpaque(false);
    	playerPanel.setLayout(new FlowLayout());
    	playerPanel.setVisible(true);
    	for (int i=0; i<numPlayers; i++) {
    		JPanel sectionPanel = new JPanel();
    		sectionPanel.setPreferredSize(new Dimension(190,220));
    		sectionPanel.setOpaque(false);
    		sectionPanel.setLayout(new BoxLayout(sectionPanel, BoxLayout.Y_AXIS));
    		addPlayerHandPanel(sectionPanel);
    		addPlayerValuePanel(sectionPanel);
    		addPlayerInfoPanel(sectionPanel);
    		playerPanel.add(sectionPanel);
    	}
    	return playerPanel;
    }
    
    /**
     * Creates Players Hand Area
     * @param myPanel Players Panel
     */
    private void addPlayerHandPanel(JPanel myPanel) {
    	JPanel playerHandPanel = new JPanel();
    	playerHandPanel.setPreferredSize(new Dimension(190,75));
    	playerHandPanel.setOpaque(false);
    	playerHandPanel.setLayout(new FlowLayout());
//    	addCard(playerHandPanel);
//    	addCard(playerHandPanel);
    	playersHandPanels.add(playerHandPanel);
    	myPanel.add(playerHandPanel);
    }
    
    /**
     * Creates Players Value Area
     * @param myPanel Players Panel
     */
    private void addPlayerValuePanel(JPanel myPanel) {
    	JPanel valuePanel = new JPanel();
    	valuePanel.setMaximumSize(new Dimension(190,0));
    	valuePanel.setOpaque(false);
    	valuePanel.setVisible(true);
    	playersValuePanels.add(valuePanel);
//    	valuePanel.add(new JLabel("TEMP"));
    	myPanel.add(valuePanel);
    }
    
    /**
     * Creates Players Info Area
     * @param myPanel Player Info Panel
     */
    private void addPlayerInfoPanel(JPanel myPanel) {
    	JPanel playerInfoPanel = new JPanel();
    	playerInfoPanel.setOpaque(false);
    	JButton hitButton = new JButton("Hit");
    	playersHitButtons.add(hitButton);
    	playerInfoPanel.add(hitButton);
    	JButton standButton = new JButton("Stand");
    	playersStandButtons.add(standButton);
    	playerInfoPanel.add(standButton);
    	JButton ddButton = new JButton("DD");
    	playersDDButtons.add(ddButton);
    	playerInfoPanel.add(ddButton);
    	JButton surrenderButton = new JButton("Surrender");
    	playersSurrenderButtons.add(surrenderButton);
    	playerInfoPanel.add(surrenderButton);
    	
    	JButton extraButton = new JButton("Split");
    	extraButton.setEnabled(false);
    	playerInfoPanel.add(extraButton);
    	
    	myPanel.add(playerInfoPanel);
    }
    
    /**
     * Clears all Card Panels Contents
     */
    private void clearHands() {
    	dealersHandPanel.removeAll();
    	for (int i=0; i<playersHandPanels.size(); i++)
    		playersHandPanels.get(i).removeAll();
    }
    
    /**
     * Adds Face Up Card to panel
     * @param myPanel Panel to add to
     * @param myCard  Card to Add
     */
    private void addCard(JPanel myPanel, Card myCard) {
    	String[] suitNames = {"spade", "heart", "club", "diamond"};
    	int cardNum  = myCard.getNumber();
    	int cardSuit = myCard.getSuit();
    	String imgString = cardNum+suitNames[cardSuit-1];
    	ImageIcon aCard = new ImageIcon("image/"+imgString+".png");
//    	JLabel singleCard = new JLabel(aCard);  
    	
    	Image image = aCard.getImage();
    	 BufferedImage buffImage = 
    	      new BufferedImage(
    	          image.getWidth(null), 
    	          image.getHeight(null), 
    	          BufferedImage.TYPE_INT_ARGB);
    	 Graphics g = buffImage.getGraphics();
    	 g.drawImage(image, 0, 0, null);
    	 
    	 try {
    		 BufferedImage[] toPaint = new BufferedImage[((GraphicComponent)myPanel.getComponent(0)).getImages().length+1];
    		 for (int i=0; i<toPaint.length-1; i++)
    			 toPaint[i] = ((GraphicComponent)myPanel.getComponent(0)).getImages()[i];
    		 toPaint[toPaint.length-1] = buffImage;
        	 GraphicComponent temp = new GraphicComponent(toPaint);
        	 myPanel.removeAll();
        	 temp.setOpaque(false);
        	 myPanel.add(temp); 
    	 }
    	 catch (Exception e) {
    		 BufferedImage[] toPaint = {buffImage};
        	 GraphicComponent temp = new GraphicComponent(toPaint);
        	 temp.setOpaque(false);
        	 myPanel.add(temp); 
    	 }
    	 
//    	myPanel.add(cards);
    	    
//    	myPanel.add(singleCard);
    }

    /**
     * Adds a Face Down card to Panel
     * @param myPanel Panel to add to
     */
    private void addCard(JPanel myPanel) {
    		ImageIcon aCard = new ImageIcon("image/faceDown.png");
        	JLabel singleCard = new JLabel(aCard);
        	myPanel.add(singleCard);
    }
    
    /**
     * Redraws All Hands
     */
    private void reDraw() {
    	dealersHandPanel.repaint();
    	dealersHandPanel.revalidate();
    	dealersInfoPanel.repaint();
    	dealersInfoPanel.revalidate();
    	for (int i=0; i<playersHandPanels.size(); i++) {
    		playersHandPanels.get(i).repaint();
    		playersHandPanels.get(i).revalidate();
    		playersValuePanels.get(i).repaint();
    		playersValuePanels.get(i).revalidate();
    	}  	
    }
    
    /**
     * Forces a Stand when Player Busts
     */
    public void forceStand() {
    	this.forceStand.doClick();
    }
    
    /**
     * Enables the next players Buttons
     */
    public void enableNextPlayer() {
    	if (currentPlayer!=numPlayers-1 && currentPlayer>-1) {
    		playersHitButtons.get(currentPlayer).setEnabled(false);
    		playersStandButtons.get(currentPlayer).setEnabled(false);
    		playersDDButtons.get(currentPlayer).setEnabled(false);
    		playersSurrenderButtons.get(currentPlayer).setEnabled(false);
    		currentPlayer++;
    		playersHitButtons.get(currentPlayer).setEnabled(true);
    		playersStandButtons.get(currentPlayer).setEnabled(true);
    		playersDDButtons.get(currentPlayer).setEnabled(true);
    		playersSurrenderButtons.get(currentPlayer).setEnabled(true);
    	}
    	else if (currentPlayer == -1) {
    		currentPlayer = 0;
    		btnNextHand.setEnabled(false);
    		btnExport.setEnabled(false);
    		playersHitButtons.get(0).setEnabled(true);
    		playersStandButtons.get(0).setEnabled(true);
    		playersDDButtons.get(0).setEnabled(true);
    		playersSurrenderButtons.get(0).setEnabled(true);
    	}
    	else {
    		playersHitButtons.get(currentPlayer).setEnabled(false);
    		playersStandButtons.get(currentPlayer).setEnabled(false);
    		playersDDButtons.get(currentPlayer).setEnabled(false);
    		playersSurrenderButtons.get(currentPlayer).setEnabled(false);
    		btnNextHand.setEnabled(true);
    		btnExport.setEnabled(true);
    		currentPlayer = -1;
    	}
    }

    /**
     * Displays All Hands on table (Dealer Card Face Down)
     * @param myList List of Hands
     */
    public void displayHands(ArrayList<ArrayList<Card>> myList) {
    	clearHands();
    	for (int i=0; i<myList.size()-1; i++)
    		for (int j=0; j<myList.get(i).size(); j++)
    			addCard(playersHandPanels.get(i), myList.get(i).get(j));
//    	addCard(dealersHandPanel);
    	addCard(dealersHandPanel, myList.get(myList.size()-1).get(0));
    	dealersInfoPanel.removeAll();
    	int singleCardValue = myList.get(myList.size()-1).get(0).getNumber();
    	String singleCardString;
    	if (singleCardValue>10)
    		singleCardString = "10";
    	else if (singleCardValue == 1)
    		singleCardString = "1 or 11";
    	else 
    		singleCardString = new Integer(singleCardValue).toString();
    	JLabel dealersValue = new JLabel("Dealers Value: "+singleCardString);
    	dealersValue.setForeground(Color.WHITE);
    	dealersInfoPanel.add(dealersValue);
    	reDraw();
    }
    
    /**
     * Display All Hand Values
     * @param myValues List of Hand Values
     */
    public void displayValues(ArrayList<ArrayList<Integer>> myValues) {
    	for (int i=0; i<myValues.size()-1; i++) {
    		String possibleValues = myValues.get(i).get(0).toString();
    		for (int j=1; j<myValues.get(i).size(); j++)
    			possibleValues = possibleValues.concat(" or " + myValues.get(i).get(j).toString());
    		playersValuePanels.get(i).removeAll();
    		JLabel playersValue = new JLabel("Players Hand: "+possibleValues);
    		playersValue.setForeground(Color.WHITE);
    		playersValuePanels.get(i).add(playersValue);
    		reDraw();
    	}
    }
    
    /**
     * Displays All Hands on table (Dealer Card Face Up)
     * @param myList List of Hands
     */
    public void revealAll(ArrayList<ArrayList<Card>> myList) {
    	clearHands();
    	for (int i=0; i<myList.size()-1; i++)
    		for (int j=0; j<myList.get(i).size(); j++)
    			addCard(playersHandPanels.get(i), myList.get(i).get(j));
    	for (int i=0; i<myList.get(myList.size()-1).size(); i++)
    		addCard(dealersHandPanel, myList.get(myList.size()-1).get(i));
    	reDraw();
    }

    /**
     * Updates dealers Value after he Plays
     * @param myList List of Players Values
     */
    public void updateDealerValue(ArrayList<ArrayList<Integer>> myList) {
    	String valueString;
    	valueString = myList.get(myList.size()-1).get(0).toString();
    	for (int i=1; i<myList.get(myList.size()-1).size(); i++)
    		valueString = valueString.concat(" or "+ myList.get(myList.size()-1).get(i).toString());
    	dealersInfoPanel.removeAll();
    	JLabel dealersValue = new JLabel("Dealers Value: "+valueString);
    	dealersValue.setForeground(Color.WHITE);
    	dealersInfoPanel.add(dealersValue);
    }
    
    /**
     * Adds Hit Listeners to all Hit Buttons
     * @param myListener Hit Listener
     */
    public void addHitListeners(ActionListener myListener) {
    	for (int i=0; i<playersHitButtons.size(); i++)
    		playersHitButtons.get(i).addActionListener(myListener);
    }
    
    /**
     * Adds Stand Listeners to all Stand Buttons
     * @param myListener Stand Listener
     */
    public void addStandListeners(ActionListener myListener) {
    	for (int i=0; i<playersStandButtons.size(); i++)
    		playersStandButtons.get(i).addActionListener(myListener);
    	forceStand.addActionListener(myListener);
    }
    
    /**
     * Adds Next Hand Listener
     * @param myListener Next Hand Listener
     */
    public void addNextHandListener(ActionListener myListener) {
    	btnNextHand.addActionListener(myListener);
    }
    
    public void addDebugListener(ActionListener myListener) {
    	this.debugCheckBox.addActionListener(myListener);
    }
    
    public void addLuckyListener(ActionListener myListener) {
    	this.luckyCheckBox.addActionListener(myListener);
    }
    
    public void addExportListener(ActionListener myListener) {
    	this.btnExport.addActionListener(myListener);
    }
    
    public void addDDListeners(ActionListener myListener) {
    	for (int i=0; i<playersDDButtons.size(); i++)
    		playersDDButtons.get(i).addActionListener(myListener);
    }
    
    public void addSurrenderListeners(ActionListener myListener) {
    	for (int i=0; i<playersSurrenderButtons.size(); i++)
    		playersSurrenderButtons.get(i).addActionListener(myListener);
    }
}